/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.ages.graphics

import javax.media.opengl.GL
import scala.collection.mutable.Queue
import scala.xml.Elem
import scala.xml.Node
import scala.xml.XML

object SpriteBufferManager{
  val spriteQueue:Queue[Sprite] = new Queue[Sprite]()

  def forceBufferSprite(spr:Sprite,gl:GL)
  {
    spriteQueue.dequeueAll(s=> s==spr)//remove this sprite from queue...
    bufferThis(spr,gl)
  }

  def spriteQueueSize = spriteQueue.size
  
  def enqueueSprite(sb:Sprite)
  {
    spriteQueue.enqueue(sb)
  }

  def queueEmpty = spriteQueue.isEmpty
  
  def bufferQueue(gl:GL){
    while(!spriteQueue.isEmpty)
    {
      buffer(gl)
    }
  }

  private def bufferThis(spr:Sprite,gl:GL)
  {
    spr.spriteBuffer_=(new SpriteBuffer(spr.filename,spr.rows,spr.cols,spr.hue))
    spr.generateDisplaylists(gl)
    spr.loaded = true
  }

  private def buffer(gl:GL)
  {
    val spr = spriteQueue.dequeue
//      println("buffering "+spr.filename)
    bufferThis(spr,gl)
  }

  def bufferNext(gl:GL)
  {
    if(!spriteQueue.isEmpty)
    {
      buffer(gl)
    }
  }
}

class SpriteBufferManager(gl:GL){

  def getDisplaylist(spriteBuffer:SpriteBuffer) {//TODO: multidimensional arrays seem....depre-broken-cated
//
//    val rows = spriteBuffer.getCols
//    val cols = spriteBuffer.getRows
////    val frames = new Array[Array[Int]](rows,cols)
//    val frames = new Array[Array[Int]](rows,cols)
//
//
////     val frames = new Array[Array[Int]](spriteBuffer.)(spriteBuffer.cols)
////        int[][] frames = new int[spriteBuffer.rows][spriteBuffer.cols];
//    for (i <- 0 to rows) {
//      for (j <- 0 to cols) {
//
//        frames(i)(j) = gl.glGenLists(1);
//
//        val frameHeight = spriteBuffer.frameHeight
//        val frameWidth = spriteBuffer.frameWidth
//
//        val size = spriteBuffer.frameHeight
//        val width = size / 2
//        val height = size / 2
//        val dim = spriteBuffer.dimRatio.toFloat
//        val framePlusI:Float = (dim.toFloat * i)
//        val framePlusJ:Float = (dim.toFloat * j)
//        gl.glNewList(frames(i)(j), GL.GL_COMPILE);
//        gl.glEnable(GL.GL_TEXTURE_2D);
//
//        gl.glEnable(GL.GL_ALPHA_TEST);
//        gl.glAlphaFunc(GL.GL_GREATER, 0);
//
//
//
//        gl.glBegin(GL.GL_POLYGON);
//        gl.glTexCoord2d(framePlusJ + 0.0f, framePlusI);
//        gl.glVertex3d(-width, height, 1.0f);	// Top Left Of The Texture and Quad
//        gl.glTexCoord2d(framePlusJ + frameWidth, framePlusI);
//        gl.glVertex3d(width, height, 1.0f);	// Bottom Left Of The Texture and Quad
//        gl.glTexCoord2d(framePlusJ + frameWidth, framePlusI + frameHeight);
//        gl.glVertex3d(width, -height, 1.0f);         // Bottom Right Of The Texture and Quad
//        gl.glTexCoord2d(framePlusJ + 0.0f, framePlusI + frameHeight);
//        gl.glVertex3d(-width, -height, 1.0f);	// Top Right Of The Texture and Quad
//        gl.glEnd();
//
//        gl.glEndList();
//
//      }
//    }
//    spriteBuffer.displayLists = frames
  }

  def drawQuad(spriteBuffer:SpriteBuffer, tx:Int, ty:Int, size:Int) {
    val frameHeight = spriteBuffer.frameHeight
    val frameWidth = spriteBuffer.frameWidth

    val width = size / 2
    val height = size / 2
    val dim = spriteBuffer.dimRatio.toFloat
    val framePlusI:Float = (dim.toFloat * tx)
    val framePlusJ:Float = (dim.toFloat * ty)

    gl.glEnable(GL.GL_TEXTURE_2D);

//    printf("frameHeight:%d, frameWidth:%d, dimRatio:%d\n",frameHeight,frameWidth,spriteBuffer.dimRatio)

    spriteBuffer.spriteSheet.bind
    //NEW
    gl.glBegin(GL.GL_POLYGON)
    gl.glTexCoord2f(framePlusJ, framePlusI+dim)
    gl.glVertex2d(0,0)	// Top Left Of The Texture and Quad
    gl.glTexCoord2f(framePlusJ + dim, framePlusI+dim)
    gl.glVertex2d(frameWidth, 0)	// Bottom Left Of The Texture and Quad
    gl.glTexCoord2f(framePlusJ + dim, framePlusI)
    gl.glVertex2d(frameWidth,frameHeight)         // Bottom Right Of The Texture and Quad
    gl.glTexCoord2f(framePlusJ + 0.0f, framePlusI)
    gl.glVertex2d(0,frameHeight)	// Top Right Of The Texture and Quad
    gl.glEnd
    spriteBuffer.spriteSheet.disable
    gl.glDisable(GL.GL_TEXTURE_2D)
  }

  def drawFrame(spriteBuffer:SpriteBuffer, meta:Node) {
    if(!meta.label.equals("frame"))
      throw new RuntimeException("XML element passed to draw in SpriteBufferManager is not frame...")

    val ileft = Integer.parseInt((meta \\ "@left").text)
    val iright = Integer.parseInt((meta \\ "@right").text)
    val itop = Integer.parseInt((meta \\ "@top").text)
    val ibottom = Integer.parseInt((meta \\ "@bottom").text)

    val size:Float = spriteBuffer.spriteSheet.getHeight
    val right = iright /  size
    val left = ileft /  size
    val bottom = ibottom /  size
    val top = itop /  size

    val frameHeight = ibottom-itop
    val frameWidth = iright-ileft

    val ratioFrameX = right-left
    val ratioFrameY = bottom-top

//    println(left,right,bottom,top,frameHeight,frameWidth)

    gl.glEnable(GL.GL_TEXTURE_2D);
//    gl.glColor4d(1,1,1,1)
    spriteBuffer.spriteSheet.bind
    gl.glBegin(GL.GL_POLYGON)
    gl.glTexCoord2f(left,bottom)
    gl.glVertex2d(0,0)	// Top Left Of The Texture and Quad
    gl.glTexCoord2f(right,bottom)
    gl.glVertex2d(frameWidth, 0)	// Bottom Left Of The Texture and Quad
    gl.glTexCoord2f(right, top)
    gl.glVertex2d(frameWidth,frameHeight)         // Bottom Right Of The Texture and Quad
    gl.glTexCoord2f(left, top)
    gl.glVertex2d(0,frameHeight)	// Top Right Of The Texture and Quad
    gl.glEnd
    spriteBuffer.spriteSheet.disable
    gl.glDisable(GL.GL_TEXTURE_2D)
  }

}
